home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Sprite 1984 - 1993
/
Sprite 1984 - 1993.iso
/
src
/
boot
/
netBoot.OpenProm
/
RCS
/
inet.c,v
< prev
next >
Wrap
Text File
|
1991-01-13
|
26KB
|
1,133 lines
head 1.3;
branch ;
access ;
symbols ;
locks ; strict;
comment @ * @;
1.3
date 91.01.13.02.43.07; author dlong; state Exp;
branches ;
next 1.2;
1.2
date 90.10.10.15.16.16; author mendel; state Exp;
branches ;
next 1.1;
1.1
date 89.06.20.10.32.00; author mendel; state Exp;
branches ;
next ;
desc
@@
1.3
log
@converted to use Sprite header files instead of Sun.
@
text
@#ifndef lint
static char sccsid[] = "@@(#)inet.c 1.12 88/02/08 Copyr 1986 Sun Micro";
#endif
/*
* Copyright (c) 1986 by Sun Microsystems, Inc.
*/
/*
* Standalone IP send and receive - specific to Ethernet
* Includes ARP and Reverse ARP
*/
#include "boot.h"
#include "sainet.h"
#include "idprom.h"
Net_EtherAddress etherbroadcastaddr = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
#define WAITCNT 2 /* 4 seconds before bitching about arp/revarp */
/*
* Fetch our Ethernet address from the ID prom
*/
myetheraddr(ea)
Net_EtherAddress *ea;
{
struct idprom id;
if (idprom(IDFORM_1, &id) != IDFORM_1) {
printf("ERROR: missing or invalid ID prom\n");
return;
}
*ea = *(Net_EtherAddress *)id.id_ether;
}
/*
* Initialize IP state
* Find out our Ethernet address and call Reverse ARP
* to find out our Internet address
* Set the ARP cache to the broadcast host
*/
inet_init(fileId, sain, tmpbuf)
register void *fileId;
register struct sainet *sain;
char *tmpbuf;
{
myetheraddr(&sain->myEther);
bzero((caddr_t)&sain->myAddr, sizeof(Net_InetAddress));
bzero((caddr_t)&sain->hisAddr, sizeof(Net_InetAddress));
sain->hisEther = etherbroadcastaddr;
revarp(fileId, sain, tmpbuf);
}
/*
* Output an IP packet
* Cause ARP to be invoked if necessary
*/
ip_output(fileId, buf, len, sain, tmpbuf)
register void *fileId;
caddr_t buf, tmpbuf;
short len;
register struct sainet *sain;
{
register Net_EtherHdr *eh;
register Net_IPHeader *ip;
eh = (Net_EtherHdr *)buf;
ip = (Net_IPHeader *)(buf + sizeof(Net_EtherHdr));
if (!inet_cmp(ip->dest, sain->hisAddr)) {
inet_copy(sain->hisAddr, ip->dest);
arp(fileId, sain, tmpbuf);
}
eh->type = NET_ETHER_IP;
eh->source = sain->myEther;
eh->destination = sain->hisEther;
/* checksum the packet */
ip->checksum = 0;
ip->checksum = ipcksum((caddr_t)ip, sizeof (Net_IPHeader));
if (len < NET_ETHER_MIN_BYTES) {
len = NET_ETHER_MIN_BYTES;
}
return !xmit_packet(fileId, buf, len);
}
/*
* Check incoming packets for IP packets
* addressed to us. Also, respond to ARP packets
* that wish to know about us.
* Returns a length for any IP packet addressed to us, 0 otherwise.
*/
ip_input(fileId, buf, sain)
register void *fileId;
caddr_t buf;
register struct sainet *sain;
{
register short len;
register Net_EtherHdr *eh;
register Net_IPHeader *ip;
register Net_ArpPacket *ea;
len = poll_packet(fileId, buf);
eh = (Net_EtherHdr *)buf;
if (eh->type == NET_ETHER_IP &&
len >= sizeof(Net_EtherHdr)+sizeof(Net_IPHeader)) {
ip = (Net_IPHeader *)(buf + sizeof(Net_EtherHdr));
#ifdef NOREVARP
if ((sain->hisAddr.s_addr & 0xFF000000) == 0 &&
NET_ETHER_COMPARE(etherbroadcastaddr,
eh->destination) == 0 &&
(in_broadaddr(sain->hisAddr) ||
in_lnaof(ip->source) == in_lnaof(sain->hisAddr))) {
sain->myAddr = ip->dest;
sain->hisAddr = ip->source;
sain->hisEther = eh->source;
}
#endif
if (!inet_cmp(ip->dest, sain->myAddr))
return (0);
return (len);
}
if (eh->type == NET_ETHER_ARP &&
len >= sizeof(Net_EtherHdr) + sizeof(Net_ArpPacket)) {
ea = (Net_ArpPacket *)buf;
if (ea->protocolType != NET_ETHER_IP)
return (0);
if (inet_cmp(ea->senderProtAddr, sain->hisAddr)) {
sain->hisEther = ea->senderEtherAddr;
}
if (ea->opcode == NET_ARP_REQUEST &&
inet_cmp(ea->targetProtAddr, sain->myAddr)) {
ea->opcode = NET_ARP_REPLY;
eh->destination = ea->senderEtherAddr;
eh->source = sain->myEther;
ea->targetEtherAddr = ea->senderEtherAddr;
inet_copy(ea->targetProtAddr, ea->senderProtAddr);
ea->senderEtherAddr = sain->myEther;
inet_copy(ea->senderProtAddr, sain->myAddr);
(void) xmit_packet(fileId, buf,
sizeof(Net_ArpPacket));
}
return (0);
}
return (0);
}
/*
* arp
* Broadcasts to determine Ethernet address given IP address
* See RFC 826
*/
arp(fileId, sain, tmpbuf)
register void *fileId;
register struct sainet *sain;
char *tmpbuf;
{
Net_ArpPacket out;
if (in_broadaddr(sain->hisAddr)
#ifdef NOREVARP
|| (sain->hisAddr.s_addr & 0xFF000000) == 0
#endif
) {
sain->hisEther = etherbroadcastaddr;
return;
}
out.header.type = NET_ETHER_ARP;
out.opcode = NET_ARP_REQUEST;
out.targetEtherAddr = etherbroadcastaddr; /* what we want */
out.targetProtAddr = sain->hisAddr;
comarp(fileId, sain, &out, tmpbuf);
}
/*
* Reverse ARP client side
* Determine our Internet address given our Ethernet address
* See RFC 903
*/
revarp(fileId, sain, tmpbuf)
register void *fileId;
register struct sainet *sain;
char *tmpbuf;
{
Net_ArpPacket out;
#ifdef NOREVARP
bzero((caddr_t)&sain->myAddr, sizeof(Net_InetAddress));
bcopy((caddr_t)&sain->myEther.ether_addr_octet[3],
(caddr_t)(&sain->myAddr)+1, 3);
#else
out.header.type = NET_ETHER_REVARP;
out.opcode = NET_RARP_REQUEST;
out.targetEtherAddr = sain->myEther;
/* What we want to find out... */
bzero((caddr_t)&out.targetProtAddr, sizeof(Net_InetAddress));
comarp(fileId, sain, &out, tmpbuf);
#endif
}
/*
* Common ARP code
* Broadcast the packet and wait for the right response.
* Fills in *sain with the results
*/
comarp(fileId, sain, out, tmpbuf)
register void *fileId;
register struct sainet *sain;
register Net_ArpPacket *out;
char *tmpbuf;
{
register Net_ArpPacket *in = (Net_ArpPacket *)tmpbuf;
register int e, count, time, feedback,len, delay = 2;
char *ind = "-\\|/";
out->header.destination = etherbroadcastaddr;
out->header.source = sain->myEther;
out->hardwareType = NET_ARP_TYPE_ETHER;
out->protocolType = NET_ETHER_IP;
out->hardwareAddrLen = sizeof(Net_EtherAddress);
out->protocolAddrLen = sizeof(Net_InetAddress);
out->senderEtherAddr = sain->myEther;
out->senderProtAddr = sain->myAddr;
feedback = 0;
for (count=0; ; count++) {
if (count == WAITCNT) {
if (out->opcode == NET_ARP_REQUEST) {
printf("\nRequesting Ethernet address for ");
inet_print(&out->targetProtAddr);
} else {
printf("\nRequesting Internet address for ");
ether_print(&out->targetEtherAddr);
}
}
e = xmit_packet(fileId, (caddr_t)out, sizeof *out);
if (!e)
printf("X\b");
else
printf("%c\b", ind[feedback++ % 4]); /* Show activity */
time = millitime() + (delay * 1000); /* broadcast delay */
while (millitime() <= time) {
len = poll_packet(fileId, tmpbuf);
if (len < sizeof(Net_ArpPacket))
continue;
if (in->protocolType != NET_ETHER_IP)
continue;
if (out->opcode == NET_ARP_REQUEST) {
if (in->header.type != NET_ETHER_ARP)
continue;
if (in->opcode != NET_ARP_REPLY)
continue;
if (in->senderProtAddr != out->targetProtAddr)
continue;
if (count >= WAITCNT) {
printf("Found at ");
ether_print(&in->senderEtherAddr);
}
sain->hisEther = in->senderEtherAddr;
return;
} else { /* Reverse ARP */
if (in->header.type != NET_ETHER_REVARP)
continue;
if (in->opcode != NET_RARP_REPLY)
continue;
if (NET_ETHER_COMPARE(in->targetEtherAddr,
out->targetEtherAddr) == 0)
continue;
if (count >= WAITCNT) {
printf("Internet address is ");
inet_print(&in->targetProtAddr);
}
inet_copy(sain->myAddr, in->targetProtAddr);
/*
* short circuit first ARP
*/
inet_copy(sain->hisAddr, in->senderProtAddr);
sain->hisEther = in->senderEtherAddr;
return;
}
}
delay = delay * 2; /* Double the request delay */
if (delay > 64) /* maximum delay is 64 seconds */
delay = 64;
reset(fileId);
}
/* NOTREACHED */
}
/*
* Return the host portion of an internet address.
*/
in_lnaof(in)
Net_InetAddress in;
{
if (NET_INET_CLASS_A_ADDR(in))
return ((in)&NET_INET_CLASS_A_HOST_MASK);
else if (NET_INET_CLASS_B_ADDR(in))
return ((in)&NET_INET_CLASS_B_HOST_MASK);
else
return ((in)&NET_INET_CLASS_C_HOST_MASK);
}
/*
* Test for broadcast IP address
*/
in_broadaddr(in)
Net_InetAddress in;
{
if (NET_INET_CLASS_A_ADDR(in)) {
in &= NET_INET_CLASS_A_HOST_MASK;
return (in == 0 || in == 0xFFFFFF);
} else if (NET_INET_CLASS_B_ADDR(in)) {
in &= NET_INET_CLASS_B_HOST_MASK;
return (in == 0 || in == 0xFFFF);
} else if (NET_INET_CLASS_C_ADDR(in)) {
in &= NET_INET_CLASS_C_HOST_MASK;
return (in == 0 || in == 0xFF);
} else
return (0);
/*NOTREACHED*/
}
/*
* Compute one's complement checksum
* for IP packet headers
*/
ipcksum(cp, count)
caddr_t cp;
register unsigned short count;
{
register unsigned short *sp = (unsigned short *)cp;
register unsigned long sum = 0;
register unsigned long oneword = 0x00010000;
count >>= 1;
while (count--) {
sum += *sp++;
if (sum >= oneword) { /* Wrap carries into low bit */
sum -= oneword;
sum++;
}
}
return (~sum);
}
inet_print(p)
Net_InetAddress *p;
{
Net_InetAddress s;
inet_copy(s, *p);
printf("%d.%d.%d.%d\n",
(s >> 24) & 0xff,
(s >> 16) & 0xff,
(s >> 8) & 0xff,
s & 0xff);
}
ether_print(ea)
Net_EtherAddress *ea;
{
printf("%x:%x:%x:%x:%x:%x\n",
NET_ETHER_ADDR_BYTE1(*ea),
NET_ETHER_ADDR_BYTE2(*ea),
NET_ETHER_ADDR_BYTE3(*ea),
NET_ETHER_ADDR_BYTE4(*ea),
NET_ETHER_ADDR_BYTE5(*ea),
NET_ETHER_ADDR_BYTE6(*ea));
}
@
1.2
log
@*** empty log message ***
@
text
@a12 1
#include "machparam.h"
a13 8
#include "saio.h"
#include "socket.h"
#include "if.h"
#include "if_arp.h"
#include "in.h"
#include "if_ether.h"
#include "in_systm.h"
#include "ip.h"
a14 1
#include "sunromvec.h"
d17 1
a17 3
#define millitime() (*romp->v_nmiclock)
struct ether_addr etherbroadcastaddr = {
a20 6
struct arp_packet {
struct ether_header arp_eh;
struct ether_arp arp_ea;
#define used_size (sizeof (struct ether_header)+sizeof(struct ether_arp))
char filler[ETHERMIN - sizeof(struct ether_arp)];
};
d28 1
a28 1
struct ether_addr *ea;
d36 1
a36 1
*ea = *(struct ether_addr *)id.id_ether;
d45 2
a46 2
inet_init(sip, sain, tmpbuf)
register struct saioreq *sip;
d50 5
a54 5
myetheraddr(&sain->sain_myether);
bzero((caddr_t)&sain->sain_myaddr, sizeof(struct in_addr));
bzero((caddr_t)&sain->sain_hisaddr, sizeof(struct in_addr));
sain->sain_hisether = etherbroadcastaddr;
revarp(sip, sain, tmpbuf);
d62 2
a63 2
ip_output(sip, buf, len, sain, tmpbuf)
register struct saioreq *sip;
d68 2
a69 2
register struct ether_header *eh;
register struct ip *ip;
d71 5
a75 9
eh = (struct ether_header *)buf;
ip = (struct ip *)(buf + sizeof(struct ether_header));
if (bcmp((caddr_t)&ip->ip_dst,
(caddr_t)&sain->sain_hisaddr,
sizeof(struct in_addr)) != 0) {
bcopy((caddr_t)&ip->ip_dst,
(caddr_t)&sain->sain_hisaddr,
sizeof (struct in_addr));
arp(sip, sain, tmpbuf);
d77 3
a79 3
eh->ether_type = ETHERTYPE_IP;
eh->ether_shost = sain->sain_myether;
eh->ether_dhost = sain->sain_hisether;
d81 4
a84 4
ip->ip_sum = 0;
ip->ip_sum = ipcksum((caddr_t)ip, sizeof (struct ip));
if (len < ETHERMIN + sizeof(struct ether_header)) {
len = ETHERMIN+sizeof(struct ether_header);
d86 1
a86 1
return (*sip->si_sif->sif_xmit)(sip->si_devdata, buf, len);
d95 2
a96 2
ip_input(sip, buf, sain)
register struct saioreq *sip;
d101 3
a103 3
register struct ether_header *eh;
register struct ip *ip;
register struct ether_arp *ea;
d105 5
a109 5
len = (*sip->si_sif->sif_poll)(sip->si_devdata, buf);
eh = (struct ether_header *)buf;
if (eh->ether_type == ETHERTYPE_IP &&
len >= sizeof(struct ether_header)+sizeof(struct ip)) {
ip = (struct ip *)(buf + sizeof(struct ether_header));
d111 8
a118 9
if ((sain->sain_hisaddr.s_addr & 0xFF000000) == 0 &&
bcmp((caddr_t)ðerbroadcastaddr,
(caddr_t)&eh->ether_dhost,
sizeof(struct ether_addr)) != 0 &&
(in_broadaddr(sain->sain_hisaddr) ||
in_lnaof(ip->ip_src) == in_lnaof(sain->sain_hisaddr))) {
sain->sain_myaddr = ip->ip_dst;
sain->sain_hisaddr = ip->ip_src;
sain->sain_hisether = eh->ether_shost;
d121 1
a121 3
if (bcmp((caddr_t)&ip->ip_dst,
(caddr_t)&sain->sain_myaddr,
sizeof(struct in_addr)) != 0)
d125 4
a128 4
if (eh->ether_type == ETHERTYPE_ARP &&
len >= sizeof(struct ether_header) + sizeof(struct ether_arp)) {
ea = (struct ether_arp *)(buf + sizeof(struct ether_header));
if (ea->arp_pro != ETHERTYPE_IP)
d130 2
a131 21
if (bcmp((caddr_t)ea->arp_spa,
(caddr_t)&sain->sain_hisaddr,
sizeof(struct in_addr)) == 0)
sain->sain_hisether = ea->arp_sha;
if (ea->arp_op == ARPOP_REQUEST &&
(bcmp((caddr_t)ea->arp_tpa,
(caddr_t)&sain->sain_myaddr,
sizeof(struct in_addr)) == 0)) {
ea->arp_op = ARPOP_REPLY;
eh->ether_dhost = ea->arp_sha;
eh->ether_shost = sain->sain_myether;
ea->arp_tha = ea->arp_sha;
bcopy((caddr_t)ea->arp_spa,
(caddr_t)ea->arp_tpa,
sizeof(ea->arp_tpa));
ea->arp_sha = sain->sain_myether;
bcopy((caddr_t)&sain->sain_myaddr,
(caddr_t)ea->arp_spa,
sizeof(ea->arp_spa));
(*sip->si_sif->sif_xmit)(sip->si_devdata, buf,
sizeof(struct arp_packet));
d133 12
d155 2
a156 2
arp(sip, sain, tmpbuf)
register struct saioreq *sip;
d160 1
a160 1
struct arp_packet out;
d162 1
a162 1
if (in_broadaddr(sain->sain_hisaddr)
d164 1
a164 1
|| (sain->sain_hisaddr.s_addr & 0xFF000000) == 0
d167 1
a167 1
sain->sain_hisether = etherbroadcastaddr;
d170 5
a174 7
out.arp_eh.ether_type = ETHERTYPE_ARP;
out.arp_ea.arp_op = ARPOP_REQUEST;
out.arp_ea.arp_tha = etherbroadcastaddr; /* what we want */
bcopy((caddr_t)&sain->sain_hisaddr,
(caddr_t)out.arp_ea.arp_tpa,
sizeof(sain->sain_hisaddr));
comarp(sip, sain, &out, tmpbuf);
d182 2
a183 2
revarp(sip, sain, tmpbuf)
register struct saioreq *sip;
d187 1
a187 1
struct arp_packet out;
d190 3
a192 3
bzero((caddr_t)&sain->sain_myaddr, sizeof(struct in_addr));
bcopy((caddr_t)&sain->sain_myether.ether_addr_octet[3],
(caddr_t)(&sain->sain_myaddr)+1, 3);
d194 3
a196 3
out.arp_eh.ether_type = ETHERTYPE_REVARP;
out.arp_ea.arp_op = REVARP_REQUEST;
out.arp_ea.arp_tha = sain->sain_myether;
d198 2
a199 2
bzero(out.arp_ea.arp_tpa, sizeof(struct in_addr));
comarp(sip, sain, &out, tmpbuf);
d208 2
a209 2
comarp(sip, sain, out, tmpbuf)
register struct saioreq *sip;
d211 1
a211 1
register struct arp_packet *out;
d214 1
a214 1
register struct arp_packet *in = (struct arp_packet *)tmpbuf;
d216 1
a216 2
char *ind = "-\|/";
struct in_addr tmp_ia;
d218 8
a225 10
out->arp_eh.ether_dhost = etherbroadcastaddr;
out->arp_eh.ether_shost = sain->sain_myether;
out->arp_ea.arp_hrd = ARPHRD_ETHER;
out->arp_ea.arp_pro = ETHERTYPE_IP;
out->arp_ea.arp_hln = sizeof(struct ether_addr);
out->arp_ea.arp_pln = sizeof(struct in_addr);
out->arp_ea.arp_sha = sain->sain_myether;
bcopy((caddr_t)&sain->sain_myaddr,
(caddr_t)out->arp_ea.arp_spa,
sizeof(out->arp_ea.arp_spa));
d230 1
a230 1
if (out->arp_ea.arp_op == ARPOP_REQUEST) {
d232 1
a232 3
bcopy((caddr_t)out->arp_ea.arp_tpa,
(caddr_t)&tmp_ia, sizeof(tmp_ia));
inet_print(tmp_ia);
d235 1
a235 1
ether_print(&out->arp_ea.arp_tha);
d238 2
a239 3
e = (*sip->si_sif->sif_xmit)(sip->si_devdata, (caddr_t)out,
sizeof *out);
if (e)
d246 2
a247 2
len = (*sip->si_sif->sif_poll)(sip->si_devdata, tmpbuf);
if (len < used_size)
d249 1
a249 1
if (in->arp_ea.arp_pro != ETHERTYPE_IP)
d251 2
a252 2
if (out->arp_ea.arp_op == ARPOP_REQUEST) {
if (in->arp_eh.ether_type != ETHERTYPE_ARP)
d254 1
a254 1
if (in->arp_ea.arp_op != ARPOP_REPLY)
d256 1
a256 3
if (bcmp((caddr_t)in->arp_ea.arp_spa,
(caddr_t)out->arp_ea.arp_tpa,
sizeof(struct in_addr)) != 0)
d260 1
a260 1
ether_print(&in->arp_ea.arp_sha);
d262 1
a262 1
sain->sain_hisether = in->arp_ea.arp_sha;
d265 1
a265 1
if (in->arp_eh.ether_type !=ETHERTYPE_REVARP)
d267 1
a267 1
if (in->arp_ea.arp_op != REVARP_REPLY)
d269 2
a270 3
if (bcmp((caddr_t)&in->arp_ea.arp_tha,
(caddr_t)&out->arp_ea.arp_tha,
sizeof (struct ether_addr)) != 0)
d275 1
a275 3
bcopy((caddr_t)in->arp_ea.arp_tpa,
(caddr_t)&tmp_ia, sizeof(tmp_ia));
inet_print(tmp_ia);
d277 1
a277 3
bcopy((caddr_t)in->arp_ea.arp_tpa,
(caddr_t)&sain->sain_myaddr,
sizeof(sain->sain_myaddr));
d281 2
a282 4
bcopy((caddr_t)in->arp_ea.arp_spa,
(caddr_t)&sain->sain_hisaddr,
sizeof(sain->sain_hisaddr));
sain->sain_hisether = in->arp_ea.arp_sha;
d291 1
a291 1
(*sip->si_sif->sif_reset)(sip->si_devdata);
d300 1
a300 1
struct in_addr in;
d302 4
a305 6
register u_long i = ntohl(in.s_addr);
if (IN_CLASSA(i))
return ((i)&IN_CLASSA_HOST);
else if (IN_CLASSB(i))
return ((i)&IN_CLASSB_HOST);
d307 1
a307 1
return ((i)&IN_CLASSC_HOST);
d314 1
a314 1
struct in_addr in;
d316 9
a324 11
register u_long i = ntohl(in.s_addr);
if (IN_CLASSA(i)) {
i &= IN_CLASSA_HOST;
return (i == 0 || i == 0xFFFFFF);
} else if (IN_CLASSB(i)) {
i &= IN_CLASSB_HOST;
return (i == 0 || i == 0xFFFF);
} else if (IN_CLASSC(i)) {
i &= IN_CLASSC_HOST;
return (i == 0 || i == 0xFF);
d353 2
a354 2
inet_print(s)
struct in_addr s;
d356 3
d360 4
a363 4
(s.s_addr >> 24) & 0xff,
(s.s_addr >> 16) & 0xff,
(s.s_addr >> 8) & 0xff,
s.s_addr & 0xff);
d367 1
a367 1
struct ether_addr *ea;
d369 7
a375 3
register u_char *p = &ea->ether_addr_octet[0];
printf("%x:%x:%x:%x:%x:%x\n", p[0], p[1], p[2], p[3], p[4], p[5]);
@
1.1
log
@Initial revision
@
text
@d1 4
a5 3
* inet.c
*
* @@(#)inet.c 1.7 88/02/08 Copyr 1986 Sun Micro
d13 13
a25 10
#include "../dev/saio.h"
#include "../h/socket.h"
#include "../dev/if.h"
#include "../h/in.h"
#include "../dev/if_ether.h"
#include "../h/in_systm.h"
#include "../h/ip.h"
#include "../h/sainet.h"
#include "../h/sunromvec.h"
#include "../h/idprom.h"
d40 2
a41 2
#define WAITCNT 2 /* 4 sec. wait for arp/revarp */
d43 1
a43 6
* Description: Fetches our Ethernet address from the ID prom
*
* Synopsis: status = myetheraddr(ea)
* status :(null)
* ea :(char *) pointer to ethernet address structure
* Routines: idprom, printf
d56 1
a56 1
d58 4
a61 13
* Description: Initialize IP state
*
* Find out our Ethernet address and call Reverse ARP.
* To find out our Internet address,
* set the ARP cache to the broadcast host
*
* Synopsis: status = inet_init(sip, sain, tmpbuf)
* status :(null)
* sip :(char *) pointer to saioreq structure
* sain :(char *) pointer to sainet structure
* tmpbuf :(char *) pointer to temporary buffer space
*
* Routines: myetheraddr, revarp
d68 3
a70 3
myetheraddr(&sain->sain_myether); /* ethernet addr from IDPROM */
sain->sain_hisaddr.s_addr = 0; /* clear address */
/* broadcast msg. */
d72 1
a72 1
revarp(sip, sain, tmpbuf); /* deter. internet address */
d74 2
a75 1
d77 2
a78 14
* Description: Output an IP packet
*
* Cause ARP to be invoked if necessary
*
* Synopsis: status = ip_output(sip, buf, len, sain, tmpbuf)
* status :(null)
* sip :(char *) pointer to saioreq structure
* buf :(char *) address pointer to buffer
* len :(short) length of IP packet
* sain :(char *) pointer to sainet structure
* tmpbuf :(char *) pointer to temporary buffer space
*
* Routines: arp, ipcksum, sif_xmit
*
a88 1
/* construct header */
a89 2
/* check destination addr */
d91 7
a97 3
if (ip->ip_dst.s_addr != sain->sain_hisaddr.s_addr) {
sain->sain_hisaddr.s_addr = ip->ip_dst.s_addr;
arp(sip, sain, tmpbuf);
d99 1
a99 1
eh->ether_type = ETHERPUP_IPTYPE;
d102 1
a102 1
/* checksum the packet */
d105 1
a105 3
/* set length of packet */
if (len < ETHERMIN+sizeof(struct ether_header))
d107 1
a107 3
/* transmit */
d110 1
a110 1
d112 4
a115 11
* Description: Check incoming packets for IP packets addressed to us.
*
* Also, respond to ARP packets that wish to know about us.
* Returns a length for any IP packet addressed to us, 0 otherwise.
*
* Synopsis: status = ip_input(sip, buf, sain)
* sip :(char *) pointer to saioreq structure
* sain :(char *) pointer to sainet structure
* buf :(char *) address pointer to buffer space for packet
*
* Routine: sif_poll, sif_xmit
a125 1
/* read packet */
a127 2
/* check header */
d129 1
a129 3
/* IP packet */
if (eh->ether_type == ETHERPUP_IPTYPE &&
d132 15
a146 4
/* make sure it's for me */
if (ip->ip_dst.s_addr != sain->sain_myaddr.s_addr)
d150 2
a151 4
/* ARP packet */
if (eh->ether_type == ETHERPUP_ARPTYPE &&
len >= sizeof(struct ether_header)+sizeof(struct ether_arp)) {
d153 1
a153 1
if (ea->arp_pro != ETHERPUP_IPTYPE)
d155 4
a158 5
if (arp_spa(ea).s_addr == sain->sain_hisaddr.s_addr)
sain->sain_hisether = arp_sha(ea);
/* send ARP reply */
d160 3
a162 1
arp_tpa(ea).s_addr == sain->sain_myaddr.s_addr) {
d164 1
a164 1
eh->ether_dhost = arp_sha(ea);
d166 8
a173 4
arp_tha(ea) = arp_sha(ea);
arp_tpa(ea) = arp_spa(ea);
arp_sha(ea) = sain->sain_myether;
arp_spa(ea) = sain->sain_myaddr;
d181 1
a181 1
d183 3
a185 10
* Description: ARP, Broadcasts to determine Ethernet address given IP address
* See RFC 826
*
* Synopsis: status = arp(sip, sain, tmpbuf)
* status :(null)
* sip :(char *) pointer to saioreq structure
* sain :(char *) pointer to sainet structure
* tmpbuf :(char *) pointer to temporary buffer space
*
* Routines: comarp, in_lnaof
d193 6
a198 4
/* deter. destination, lnaof
* gets host portion of addr */
if (in_lnaof(sain->sain_hisaddr) == INADDR_ANY ||
(in_lnaof(sain->sain_hisaddr) & INADDR1_ANY) == INADDR1_ANY) {
d202 1
a202 2
/* set up ARP packet */
out.arp_eh.ether_type = ETHERPUP_ARPTYPE;
d204 11
a214 17
arp_tha(&out.arp_ea) = etherbroadcastaddr; /* what we want */
arp_tpa(&out.arp_ea).s_addr = sain->sain_hisaddr.s_addr;
comarp(sip, sain, &out, tmpbuf); /* transmit */
}
/*
* Description: Reverse ARP client side
* Determine our Internet address given our Ethernet address
* See RFC 903
*
* Synopsis: status = revarp(sip, sain, tmpbuf)
* status :(null)
* sip :(char *) pointer to saioreq structure
* sain :(char *) pointer to sainet structure
* tmpbuf :(char *) pointer to temporary buffer space
*
a221 1
/* set up ARP packet */
d223 6
a228 1
out.arp_eh.ether_type = ETHERPUP_REVARPTYPE;
d230 11
a240 19
arp_tha(&out.arp_ea) = sain->sain_myether;
arp_tpa(&out.arp_ea).s_addr = 0; /* what we want to find out */
comarp(sip, sain, &out, tmpbuf); /* transmit */
}
/*
* Description: Common ARP code
* Broadcast the packet and wait for the right response.
* Fills in *sain with the results
*
* Synopsis: status = comarp(sip, sain, out, tmpbuf)
* status :(null)
* sip :(char *) pointer to saioreq structure
* sain :(char *) pointer to sainet structure
* out :(char *) pointer to ARP packet
* tmpbuf :(char *) pointer to temporary buffer space
*
* Routines: bcmp, ether_print, inet_print, sif_xmit,
d249 3
a251 3
register int e, count, time, feedback, len, delay = 2;
char *ind = "-\\|/";
/* fill the header */
d255 2
a256 2
out->arp_ea.arp_hrd = ARPHRD_ETHER;
out->arp_ea.arp_pro = ETHERPUP_IPTYPE;
d259 4
a262 2
arp_sha(&out->arp_ea) = sain->sain_myether;
arp_spa(&out->arp_ea).s_addr = sain->sain_myaddr.s_addr;
a265 1
/* timeout message */
d268 4
a271 2
printf("Requesting Ethernet address for ");
inet_print(arp_tpa(&out->arp_ea));
d273 2
a274 2
printf("Requesting Internet address for ");
ether_print(&arp_tha(&out->arp_ea));
a276 2
/* transmit */
d279 4
a282 8
#ifdef SUN3F
/* Sun-3/F runs at 20 MHZ */
time = millitime() + (delay * 800); /* broadcast delay */
#else
time = millitime() + (delay * 1000); /* broadcast delay */
#endif SUN3F
printf("%c\b", ind[feedback++ % 4]); /* Show activity */
d284 1
a284 1
/* poll for reply */
a286 2
/* check length */
d289 1
a289 2
/* IP packet, waiting for ARP */
if (in->arp_ea.arp_pro != ETHERPUP_IPTYPE)
a290 1
/* ARP packet */
d292 1
a292 1
if (in->arp_eh.ether_type != ETHERPUP_ARPTYPE)
d296 3
a298 2
if (arp_spa(&in->arp_ea).s_addr !=
arp_tpa(&out->arp_ea).s_addr)
a299 3
/* timeout message */
d302 1
a302 1
ether_print(&arp_sha(&in->arp_ea));
d304 1
a304 1
sain->sain_hisether = arp_sha(&in->arp_ea);
d307 1
a307 2
if (in->arp_eh.ether_type !=ETHERPUP_REVARPTYPE)
d311 3
a313 3
if (bcmp((caddr_t)&arp_tha(&in->arp_ea),
(caddr_t)&arp_tha(&out->arp_ea),
sizeof (struct ether_addr)) != 0)
a314 5
/* print IP address */
printf("Using IP Address ");
inet_print(arp_tpa(&in->arp_ea));
/* short circuit first ARP */
d316 16
a331 3
sain->sain_myaddr = arp_tpa(&in->arp_ea);
sain->sain_hisaddr = arp_spa(&in->arp_ea);
sain->sain_hisether = arp_sha(&in->arp_ea);
a334 1
delay = delay * 2; /* Double the request delay */
d336 2
a337 1
if (delay > 64) /* max. delay is 64 seconds */
d339 1
a339 1
/* reset ethernet */
d344 1
a344 1
d346 1
a346 7
* Description: Return the host portion of an internet address.
*
* Synopsis: status = in_lnaof(in)
* status : host addr
* in :(in_addr) pointer to internet address
*
* Routines: ntohl
d360 23
a382 1
d384 2
a385 6
* Description: Compute one's complement checksum for IP packet headers
*
* Synopsis: status = ipcksum(cp, count)
* status : checksum
* cp :(char *) pointer to IP packet
* count :(u_short) length of IP packet
d405 1
a405 8
/*
* Description: Prints the internet address
*
* Synopsis: status = inet_print(s)
* status :(null)
* s :(char *) pointer to internet address
*/
d409 6
a414 4
int len = 2;
printf("%d.%d.%d.%d = ", s.S_un.S_un_b.s_b1, s.S_un.S_un_b.s_b2,
s.S_un.S_un_b.s_b3, s.S_un.S_un_b.s_b4);
a415 14
printhex(s.S_un.S_un_b.s_b1, len);
printhex(s.S_un.S_un_b.s_b2, len);
printhex(s.S_un.S_un_b.s_b3, len);
printhex(s.S_un.S_un_b.s_b4, len);
printf("\n");
}
/*
* Description: Prints the ethernet address
*
* Synopsis: status = ether_print(s)
* status :(null)
* s :(char *) pointer to ethernet address
*/
@